package com.tengju.bff.interfaces.app.domination.facade;

import com.beust.jcommander.internal.Lists;
import com.tengju.bff.interfaces.app.domination.assembler.DominationAssembler;
import com.tengju.bff.interfaces.app.domination.vo.*;
import com.tengju.data.application.star.StarIndicatorService;
import com.tengju.data.domain.model.clickhouse.OdsBigdataStarIndicatorStatRepository;
import com.tengju.data.domain.model.clickhouse.star.*;
import com.tengju.data.domain.model.user.*;
import com.tengju.data.domain.shared.DateUtil;
import com.tengju.data.domain.shared.IdObject;
import com.tengju.user.application.shared.ApplicationException;
import com.tengju.user.application.shared.ApplicationExceptionCode;
import com.tengju.user.application.user.UserDocumentService;
import com.tengju.user.application.user.UserInfoService;
import com.tengju.user.application.user.dto.UserSearchForm;
import com.tengju.user.domain.model.doc.UserDocument;
import com.tengju.user.domain.model.user.DominationMemberNote;
import com.tengju.user.domain.model.user.DominationMemberNoteRepository;
import com.tengju.user.domain.model.user.UserInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class DominationTeamFacade {

    @Autowired
    DominationDetailRepository dominationDetailRepository;

    @Autowired
    UserInfoService userInfoService;

    @Autowired
    UserDocumentService userDocumentService;

    @Autowired
    OdsBigdataStarIndicatorStatRepository odsBigdataStarIndicatorStatRepository;

    @Autowired
    StarIndicatorService starIndicatorService;

    @Autowired
    DominationMemberNoteRepository dominationMemberNoteRepository;

    @Value("${redis.cache.switch}")
    public boolean cacheSwitch;


    @Cacheable(value = "default_cache",
            keyGenerator = "redisCacheKeyGenerator",
            condition = "#root.target.cacheSwitch")
    public DominationMemberNumVO memberQuantity(UserIdCode idCode) {

        DominationDetail dominationDetail = dominationDetailRepository.getByIdCode(idCode);

        if (dominationDetail == null) {
            throw ApplicationException.error(ApplicationExceptionCode.SYSTEM_BUSY);
        }

        //获取管辖团队明细
        Map<StarRoleEnum, Map<StarLevelEnum, Integer>> dominationTeamMemberNum =
                dominationDetail.getDominationTeamMemberNum();

        return DominationAssembler.assemblerToVO(dominationTeamMemberNum);

    }

    @Cacheable(value = "default_cache",
            keyGenerator = "redisCacheKeyGenerator",
            condition = "#root.target.cacheSwitch")
    public DominationMemberListVO memberList(DominationMemberListForm listForm, com.tengju.user.domain.model.user.UserIdCode idCode) {

        DominationMemberListVO dominationMemberListVO = new DominationMemberListVO();
        dominationMemberListVO.setPageIndex(listForm.getPageIndex());
        dominationMemberListVO.setPageSize(listForm.getPageSize());

        //查询获取管辖等级
        com.tengju.user.domain.model.user.DominationLevelEnum dominationLevelEnum =
                userInfoService.getDominationLevel(new com.tengju.user.domain.model.user.UserIdCode(idCode.getValue()));
        DominationLevelEnum dominationLevel =
                DominationLevelEnum.fromVal(dominationLevelEnum.getVal());

        //根据手机号，昵称（模糊），备注（模糊）搜索
        List<UserIdCode> idCodes = Lists.newArrayList();
        if (!StringUtils.isEmpty(listForm.getSearchText())) {
            idCodes = searchByText(listForm.getSearchText(), dominationLevel, idCode);
            if (CollectionUtils.isEmpty(idCodes)) {
                dominationMemberListVO.setTotal(0);
                return dominationMemberListVO;
            }
        }

        if (CollectionUtils.isEmpty(listForm.getStarLevel())) {
            dominationMemberListVO.setTotal(0);
            return dominationMemberListVO;
        }
        List<StarLevelEnum> starLevels = listForm.getStarLevel().stream()
                .map(StarLevelEnum::parseByStarLevel).filter(Objects::nonNull)
                .collect(Collectors.toList());

        IsDirect isDirect = IsDirect.parseByVal(listForm.getIsDirectlyUnder());

        //count
        Integer total = dominationDetailRepository
                .customCount(idCodes, starLevels,dominationLevel,new UserIdCode(idCode.getValue()),isDirect);
        dominationMemberListVO.setTotal(total);
        if (listForm.getOffset() >= total) {
            return dominationMemberListVO;
        }

        //排序条件
        DominationMemberSortType sortType = DominationMemberSortType.fromVal(listForm.getSortType());

        List<DominationDetail> dominationDetails = dominationDetailRepository
                .customList(idCodes, starLevels, dominationLevel, new UserIdCode(idCode.getValue()),
                        isDirect, sortType, listForm.getOffset(), listForm.getPageSize());

        if (CollectionUtils.isEmpty(dominationDetails)) {
            throw ApplicationException.error(ApplicationExceptionCode.SYSTEM_BUSY);
        }

        //管辖团队用户idCode
        List<com.tengju.user.domain.model.user.UserIdCode> idCodeList =
                dominationDetails.stream().map(DominationDetail::getIdCode).map(IdObject::getValue)
                        .map(com.tengju.user.domain.model.user.UserIdCode::new).collect(Collectors.toList());
        //用户基础信息
        UserSearchForm searchForm = new UserSearchForm();
        searchForm.setIdCodes(idCodeList);
        Page<UserDocument> userDocuments = userDocumentService.search(searchForm);

        //备注
        List<DominationMemberNote> dominationMemberNoteList =
                dominationMemberNoteRepository.queryByLeaderIdAndSubordinateIds(idCode, idCodeList);

        List<DominationMemberDetailVO> dominationMemberDetailVOList = DominationAssembler.assemblerToVO(dominationDetails, userDocuments, dominationMemberNoteList);
        dominationMemberListVO.setDominationMemberDetailList(dominationMemberDetailVOList);

        return dominationMemberListVO;

    }

    private List<UserIdCode> searchByText(String text, DominationLevelEnum dominationLevel, com.tengju.user.domain.model.user.UserIdCode idCode) {
        List<UserIdCode> idCodes= Lists.newArrayList();

        UserSearchForm searchForm = new UserSearchForm();
        searchForm.belongOwner(dominationLevel,idCode);
        searchForm.setKeyWords(text);
        Page<UserDocument> userDocuments = userDocumentService.search(searchForm);
        if (userDocuments.getTotalPages() <= 0) {
            return idCodes;
        }
        idCodes = userDocuments.stream().map(UserDocument::getIdCode)
                .map(UserIdCode::new).collect(Collectors.toList());
        return idCodes;

    }

    @Cacheable(value = "default_cache",
            keyGenerator = "redisCacheKeyGenerator",
            condition = "#root.target.cacheSwitch")
    public NewMemberInfoNumVO memberNewNum(UserIdCode idCode) {

        //获取当前用户管辖等级
        com.tengju.user.domain.model.user.DominationLevelEnum dominationLevelEnum =
                userInfoService.getDominationLevel(new com.tengju.user.domain.model.user.UserIdCode(idCode.getValue()));
        DominationLevelEnum dominationLevel =
                DominationLevelEnum.fromVal(dominationLevelEnum.getVal());

        //本月时间区间
        LocalDateTime timeFrom = DateUtil.getFirstDayOfMonthMin();
        LocalDateTime timeTo = LocalDateTime.now();

        //count
        DominationMemberNew dominationMemberNew =
                dominationDetailRepository
                        .countNewMemberCurrentMonth(idCode, dominationLevel,null,timeFrom,timeTo);

        //明细
        List<UpgradingDetail> upgradingDetails = Lists.newArrayList();
        if (dominationMemberNew.hasNewMember()) {
            upgradingDetails = dominationDetailRepository
                    .queryNewMemberCurrentMonth(idCode,dominationLevel,null,timeFrom,timeTo,0,2);
        }

        if (CollectionUtils.isEmpty(upgradingDetails)) {
            return NewMemberInfoNumVO.zero();
        }

        List<com.tengju.user.domain.model.user.UserIdCode> idCodes = getIdCodes(upgradingDetails);

        List<UserInfo> userInfos = userInfoService.batchGetUserInfo(idCodes);

        return DominationAssembler.assemblerToVO(dominationMemberNew, upgradingDetails, userInfos);

    }


    @Cacheable(value = "default_cache",
            keyGenerator = "redisCacheKeyGenerator",
            condition = "#root.target.cacheSwitch")
    public NewMemberDetailListVO newMemberList(NewMemberDetailListForm form,UserIdCode idCode) {

        NewMemberDetailListVO result = new NewMemberDetailListVO();
        result.setPageIndex(form.getPageIndex());
        result.setPageSize(form.getPageSize());


        //获取当前用户管辖等级
        com.tengju.user.domain.model.user.DominationLevelEnum dominationLevelEnum =
                userInfoService.getDominationLevel(new com.tengju.user.domain.model.user.UserIdCode(idCode.getValue()));
        DominationLevelEnum dominationLevel =
                DominationLevelEnum.fromVal(dominationLevelEnum.getVal());

        //本月时间区间
        LocalDateTime timeFrom = DateUtil.getFirstDayOfMonthMin();
        LocalDateTime timeTo = LocalDateTime.now();


        if (CollectionUtils.isEmpty(form.getStarLevel())) {
            result.setTotal(0);
            return result;
        }
        List<StarLevelEnum> levelList = form.getStarLevel().stream()
                .map(StarLevelEnum::parseByStarLevel).collect(Collectors.toList());

        //count
        DominationMemberNew dominationMemberNew =
                dominationDetailRepository
                        .countNewMemberCurrentMonth(idCode, dominationLevel,levelList,timeFrom,timeTo);
        Integer total = dominationMemberNew.getTotal(levelList);
        result.setTotal(total);

        //明细
        List<UpgradingDetail> upgradingDetails = Lists.newArrayList();
        if (total >= form.getOffset()) {
            upgradingDetails = dominationDetailRepository
                    .queryNewMemberCurrentMonth(idCode,dominationLevel,levelList,timeFrom,timeTo,form.getOffset(),form.getPageSize());
        }

        if (CollectionUtils.isEmpty(upgradingDetails)) {
            return result;
        }
        List<com.tengju.user.domain.model.user.UserIdCode> idCodes = getIdCodes(upgradingDetails);
        UserSearchForm searchForm = new UserSearchForm();
        searchForm.setIdCodes(idCodes);
        Page<UserDocument> userDocuments = userDocumentService.search(searchForm);

        //聚合所有所有管辖leader的idCode
        for (UserDocument userDocument : userDocuments) {
            Long ownerGenOperatorIdCode = userDocument.getOwnerGenOperatorIdCode();
            Long ownerCityIdCode = userDocument.getOwnerCityIdCode();
            Long parentIdCode = userDocument.getParentIdCode();
            if (ownerGenOperatorIdCode != null && ownerGenOperatorIdCode > 0) {
                idCodes.add(new com.tengju.user.domain.model.user.UserIdCode(ownerGenOperatorIdCode));
            }
            if (ownerCityIdCode != null && ownerCityIdCode > 0) {
                idCodes.add(new com.tengju.user.domain.model.user.UserIdCode(ownerCityIdCode));
            }
            if (parentIdCode != null && parentIdCode > 0) {
                idCodes.add(new com.tengju.user.domain.model.user.UserIdCode(parentIdCode));
            }
        }

        List<UserInfo> userInfos = userInfoService.batchGetUserInfo(idCodes);
        List<NewMemberDetailVO> newMemberDetailVOList = DominationAssembler.assemblerToVO(upgradingDetails, userInfos, userDocuments);
        result.setNewMemberDetailVOList(newMemberDetailVOList);
        return result;
    }

    @Cacheable(value = "default_cache",
            keyGenerator = "redisCacheKeyGenerator",
            condition = "#root.target.cacheSwitch")
    public MemberUpcomingNumVO upcomingMemberNum(UserIdCode idCode) {

        DominationLevelEnum dominationLevel = getDominationLevel(idCode);
        DominationUpComing dominationUpComing =
                dominationDetailRepository.countUpComingMemberByCurrentStarLevel(idCode, dominationLevel, null);

        if(dominationUpComing.totalNum() <= 0) {
            return new MemberUpcomingNumVO(new MemberUpcomingNumDetailVO(0,null),
                    new MemberUpcomingNumDetailVO(0,null),
                    new MemberUpcomingNumDetailVO(0,null));
        }
        //即将晋升运营商用户
        List<StarChangeNoticeRecord> operatorNoticeRecords = null;
        if (dominationUpComing.operatorNum() > 0) {
            operatorNoticeRecords = dominationDetailRepository
                    .queryUpComingMemberByCurrentStarLevel(idCode, dominationLevel,
                            List.of(StarLevelEnum.EC,StarLevelEnum.SEC,StarLevelEnum.EEC), 0, 2);
        }
        //即将晋升服务商用户
        List<StarChangeNoticeRecord> serviceProviderNoticeRecords = null;
        if (dominationUpComing.serviceProviderNum() > 0) {
            serviceProviderNoticeRecords = dominationDetailRepository
                    .queryUpComingMemberByCurrentStarLevel(idCode, dominationLevel,
                            List.of(StarLevelEnum.CITY_STAR_ONE,StarLevelEnum.CITY_STAR_TWO,StarLevelEnum.CITY_STAR_THREE,StarLevelEnum.CITY_STAR_FOUR), 0, 2);
        }
        //即将晋升经销商用户
        List<StarChangeNoticeRecord> dealerNoticeRecords = null;
        if (dominationUpComing.dealerNum() > 0) {
            dealerNoticeRecords = dominationDetailRepository
                    .queryUpComingMemberByCurrentStarLevel(idCode, dominationLevel,
                            List.of(StarLevelEnum.NONE), 0, 2);
        }

        List<UserIdCode> dataIdCodes = getIdCodes(operatorNoticeRecords, serviceProviderNoticeRecords,dealerNoticeRecords);
        List<com.tengju.user.domain.model.user.UserIdCode> userIdCodes = dataIdCodes.stream().map(IdObject::getValue).map(com.tengju.user.domain.model.user.UserIdCode::new).collect(Collectors.toList());
        //未达标指标值
        Map<UserIdCode, List<StarIndicator>> notReachIndicator = starIndicatorService.getNotReachIndicator(dataIdCodes);
        //用户信息
        List<UserInfo> userInfos = userInfoService.batchGetUserInfo(userIdCodes);


        return DominationAssembler.assemblerToVO(dominationUpComing,operatorNoticeRecords,serviceProviderNoticeRecords,
                dealerNoticeRecords,userInfos,notReachIndicator);

    }


    @Cacheable(value = "default_cache",
            keyGenerator = "redisCacheKeyGenerator",
            condition = "#root.target.cacheSwitch")
    public MemberUpcomingListVO upcomingMemberList(MemberUpcomingListForm form,UserIdCode idCode) {

        MemberUpcomingListVO memberUpcomingListVO = new MemberUpcomingListVO();
        memberUpcomingListVO.setPageIndex(form.getPageIndex());
        memberUpcomingListVO.setPageSize(form.getPageSize());

        DominationLevelEnum dominationLevel = getDominationLevel(idCode);

        if (CollectionUtils.isEmpty(form.getTargetStarLevel())) {
            memberUpcomingListVO.setTotal(0);
            return memberUpcomingListVO;
        }

        List<StarLevelEnum> targetStarLevelList = form.getTargetStarLevel().stream()
                .map(StarLevelEnum::parseByStarLevel).collect(Collectors.toList());
        List<StarLevelEnum> currentStarLevelList = Lists.newArrayList();
        if (!CollectionUtils.isEmpty(form.getCurrentStarLevel())) {
            currentStarLevelList = form.getCurrentStarLevel().stream()
                    .map(StarLevelEnum::parseByStarLevel).collect(Collectors.toList());
        }

        //总数查询
        DominationUpComing dominationUpComing =
                dominationDetailRepository.countUpComingMemberByUpComingStarLevel(idCode, dominationLevel, targetStarLevelList,currentStarLevelList);
        Integer total = dominationUpComing.getTotal(targetStarLevelList);
        memberUpcomingListVO.setTotal(total);

        if (total <= form.getOffset()) {
            return memberUpcomingListVO;
        }

        List<StarChangeNoticeRecord> starChangeNoticeRecords = dominationDetailRepository
                .queryUpComingMemberByUpComingStarLevel(idCode, dominationLevel,
                        targetStarLevelList,currentStarLevelList, form.getOffset(), form.getPageSize());

        List<UserIdCode> dataIdCodes = starChangeNoticeRecords.stream().map(StarChangeNoticeRecord::getIdCode).collect(Collectors.toList());
        List<com.tengju.user.domain.model.user.UserIdCode> userIdCodes = dataIdCodes.stream().map(IdObject::getValue).map(com.tengju.user.domain.model.user.UserIdCode::new).collect(Collectors.toList());

        UserSearchForm searchForm = new UserSearchForm();
        searchForm.setIdCodes(userIdCodes);
        Page<UserDocument> userDocuments = userDocumentService.search(searchForm);

        List<com.tengju.user.domain.model.user.UserIdCode> allIdCodes = Lists.newArrayList();

        //todo 复用
        //所属运营商
        List<com.tengju.user.domain.model.user.UserIdCode> genOperatorIdCodes =
                userDocuments.stream().map(UserDocument::getOwnerGenOperatorIdCode)
                        .filter(ownerGenOperatorIdCode -> ownerGenOperatorIdCode != null && ownerGenOperatorIdCode > 0)
                        .map(com.tengju.user.domain.model.user.UserIdCode::new).collect(Collectors.toList());
        allIdCodes.addAll(genOperatorIdCodes);
        //所属服务商
        List<com.tengju.user.domain.model.user.UserIdCode> genServiceProviderIdCodes =
                userDocuments.stream().map(UserDocument::getOwnerCityIdCode)
                        .filter(ownerCityIdCode -> ownerCityIdCode != null && ownerCityIdCode > 0)
                        .map(com.tengju.user.domain.model.user.UserIdCode::new).collect(Collectors.toList());
        allIdCodes.addAll(genServiceProviderIdCodes);
        //所属上级
        List<com.tengju.user.domain.model.user.UserIdCode> genParentIdCodes =
                userDocuments.stream().map(UserDocument::getParentIdCode)
                        .filter(parentIdCode -> parentIdCode != null && parentIdCode > 0)
                        .map(com.tengju.user.domain.model.user.UserIdCode::new).collect(Collectors.toList());
        allIdCodes.addAll(genParentIdCodes);

        List<UserInfo> userInfos = userInfoService.batchGetUserInfo(allIdCodes);
        //未达标指标值
        Map<UserIdCode, List<StarIndicator>> notReachIndicator = starIndicatorService.getNotReachIndicator(dataIdCodes);

        List<MemberUpcomingDetailVO> memberUpcomingDetailList = Lists.newArrayList();
        for (StarChangeNoticeRecord starChangeNoticeRecord : starChangeNoticeRecords) {
            MemberUpcomingDetailVO memberUpcomingDetailVO = DominationAssembler
                    .assemblerToVO(starChangeNoticeRecord, userDocuments, notReachIndicator, userInfos);
            memberUpcomingDetailList.add(memberUpcomingDetailVO);
        }

        memberUpcomingListVO.setMemberUpcomingDetailList(memberUpcomingDetailList);

        return memberUpcomingListVO;

    }



    private List<UserIdCode> getIdCodes(List<StarChangeNoticeRecord> operatorNoticeRecords, List<StarChangeNoticeRecord> serviceProviderNoticeRecords, List<StarChangeNoticeRecord> dealerNoticeRecords) {
        List<UserIdCode> idCodes = Lists.newArrayList();
        if (!CollectionUtils.isEmpty(operatorNoticeRecords)) {
            List<UserIdCode> idCodeList = operatorNoticeRecords.stream().map(StarChangeNoticeRecord::getIdCode).collect(Collectors.toList());
            idCodes.addAll(idCodeList);
        }
        if (!CollectionUtils.isEmpty(serviceProviderNoticeRecords)) {
            List<UserIdCode> idCodeList = serviceProviderNoticeRecords.stream().map(StarChangeNoticeRecord::getIdCode).collect(Collectors.toList());
            idCodes.addAll(idCodeList);
        }
        if (!CollectionUtils.isEmpty(dealerNoticeRecords)) {
            List<UserIdCode> idCodeList = dealerNoticeRecords.stream().map(StarChangeNoticeRecord::getIdCode).collect(Collectors.toList());
            idCodes.addAll(idCodeList);
        }
        return idCodes;
    }

    private List<com.tengju.user.domain.model.user.UserIdCode> getIdCodes(List<UpgradingDetail> upgradingDetails) {
        return upgradingDetails.stream()
                .map(UpgradingDetail::getIdCode).map(IdObject::getValue)
                .map(com.tengju.user.domain.model.user.UserIdCode::new).collect(Collectors.toList());
    }

    private DominationLevelEnum getDominationLevel(UserIdCode idCode) {
        //获取当前用户管辖等级
        UserInfo userInfo = userInfoService.getUserInfo(new com.tengju.user.domain.model.user.UserIdCode(idCode.getValue()));
        if (userInfo == null) {
            throw ApplicationException.error(ApplicationExceptionCode.INVALID_DATA,"用户不存在");
        }
        return DominationLevelEnum.parseByStarLevel(StarLevelEnum.parseByStarLevel(userInfo.starLevel().getCode()));
    }



    public Boolean editRemark(com.tengju.user.domain.model.user.UserIdCode leaderIdCode, com.tengju.user.domain.model.user.UserIdCode subordinateIdCode, String remark) {
        return dominationMemberNoteRepository.edit(leaderIdCode,subordinateIdCode,remark);
    }

}